home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / demostu2 / texture2.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-12-15  |  10.7 KB  |  619 lines

  1. PROGRAM Texture2;
  2. {
  3.   Flat Shaded Texture Mapping
  4.   - by Bjarke Viksφe
  5.   aug 1994
  6.  
  7.   Works the same way as "texture1.pas".
  8.   Texture is only in 16 colours.
  9.   So palette is set up to make it easy to fade from one shade to another.
  10.   No real-time colour map translations - though it could have been a
  11.   nice feature.
  12.   And the light is still a fake. It depends on the polygons surface area!
  13.   (hey, it's still going 70 fps on my 40Mhz '486. Really cool, hehe)
  14.  
  15.   Picture is an 320x200x256 ILBM/IFF pix called 'marbl16.lbm'.
  16. }
  17.  
  18. {$A+,B-,G+,E+,I+,N-,X+}
  19. {$C FIXED PRELOAD PERMANENT}
  20.  
  21. {{$DEFINE DEBUG}
  22.  
  23.  
  24. USES
  25.     DEMOINIT,ILBM256,PICTURE;
  26.  
  27. CONST
  28.     NUMBER_FACES = 6;
  29.     NUMBER_COORDS = 8;
  30.     BOX = 110; {size of box}
  31.  
  32. TYPE
  33.     SlopeType = array[0..319*2] of integer;
  34.  
  35.     FaceType = RECORD
  36.         l1,l2,l3,l4 : byte;
  37.     end;
  38.  
  39.  
  40. VAR
  41.     slope,textureslope : SlopeType;
  42.     face : array[1..NUMBER_FACES] of FaceType;
  43.     light : array[1..NUMBER_FACES] of byte;
  44.     cbuffer : array[0..NUMBER_COORDS*2-1] of integer;
  45.  
  46.     minx,maxx : integer;
  47.  
  48.     sinustabel : array[0..639] of integer;
  49.     v1,v2,v3 : word;
  50.     cos1,sin1,cos2,sin2,cos3,sin3 : integer;
  51.  
  52.     texture : pScreen;
  53.  
  54.  
  55. CONST
  56.     display1 : word = $0000;
  57.     display2 : word = $4000;
  58.     {setup coords for a box}
  59.     coords : array[0..NUMBER_COORDS*3-1] of integer =
  60.         (box,box,-box, -box,box,-box, -box,-box,-box, box,-box,-box,
  61.         box,box,box, -box,box,box, -box,-box,box, box,-box,box);
  62.  
  63.  
  64. (*------------------------------------------------*)
  65.  
  66. procedure SetupSinus;
  67. var
  68.     i : integer;
  69.     v, vadd : real;
  70. begin
  71.     v:=0.0;
  72.     vadd:=(2.0*pi/512.0);
  73.     for i:=0 to 639 do begin
  74.         sinustabel[i]:=round(sin(v)*32767);
  75.         v:=v+vadd;
  76.     end;
  77. end;
  78.  
  79. procedure SetupFaces;
  80. {setup faces. Makes sure face keeps track of which coordinates it uses!}
  81. begin
  82.     with face[1] do begin l1:=3; l2:=2; l3:=1; l4:=0; end;
  83.     with face[2] do begin l1:=4; l2:=5; l3:=6; l4:=7; end;
  84.     with face[3] do begin l1:=0; l2:=1; l3:=5; l4:=4; end;
  85.     with face[4] do begin l1:=1; l2:=2; l3:=6; l4:=5; end;
  86.     with face[5] do begin l1:=2; l2:=3; l3:=7; l4:=6; end;
  87.     with face[6] do begin l1:=3; l2:=0; l3:=4; l4:=7; end;
  88. end;
  89.  
  90. procedure InitDemo;
  91. var
  92.     i,j,k : word;
  93.     factor : word;
  94. begin
  95.     Screen_Off;
  96.     ClearWholeScreen;
  97.     SetupSinus;
  98.     SetupFaces;
  99.  
  100.     New(texture);
  101.     LoadPix(texture,'marbl16.lbm');
  102.     {picture is 320x200. Need to convert it to 256x128}
  103.     j:=0; k:=0;
  104.     for i:=1 to 128 do begin
  105.         Move(texture^[j],texture^[k],128);
  106.         inc(j,320);
  107.         inc(k,256);
  108.     end;
  109.     {set up colour map to ease shade calculations}
  110.     {colours are made as 16 shades of the texture's 16 colours}
  111.     k:=1;
  112.     factor:=16;
  113.     for i:=1 to 16 do begin
  114.         for j:=1 to 16*3 do begin
  115.             CMAP[k]:=CMAP[j] * 16 DIV factor;
  116.             inc(k);
  117.         end;
  118.         inc(factor,3);
  119.     end;
  120.     SetCMAP;
  121.  
  122.     v1:=0; v2:=0; v3:=0;
  123.  
  124.     Screen_On;
  125. end;
  126.  
  127. procedure UninitDemo;
  128. begin
  129.     Dispose(texture);
  130. end;
  131.  
  132.  
  133. (*------------------------------------------------*)
  134.  
  135. procedure SwapDisplay;
  136. var
  137.     temp : word;
  138. begin
  139.     temp:=display2;
  140.     display2:=display1;
  141.     display1:=temp;
  142.     SetAddress(Ptr(SEGA000,display2));
  143. end;
  144.  
  145. procedure ClearScreen; assembler;
  146. {Clear video memory}
  147. asm
  148.     mov    dx,$3C4
  149.     mov    ax,$0F02
  150.     out    dx,ax
  151.  
  152.     mov    es,[SEGA000]
  153.     mov    di,[display1]
  154.     add    di,(30*WIDTH)+16
  155.     mov    dx,140
  156.     xor ax,ax
  157.     mov    bx,48/2
  158. @loop:
  159.     mov    cx,bx
  160.     rep stosw
  161.     add    di,WIDTH-48
  162.     dec    dl
  163.     jnz    @loop
  164. end;
  165.  
  166.  
  167. (*------------------------------------------------*)
  168.  
  169. procedure ClearSlope; assembler;
  170. asm
  171.     mov    ax,ds
  172.     mov    es,ax
  173.     lea    di,slope
  174.     DB LONG; mov ax,$8000; DW $8000;
  175.     cld
  176.     mov    cx,TYPE(slopetype)/4
  177.     rep; DB LONG; stosw
  178. end;
  179.  
  180. procedure CalcSlope(l1,l2 : integer; tex1x,tex2x,tex1y,tex2y : word); assembler;
  181. {Calc edge buffer for line drawing/texture mapping.
  182.  tex1x/tex1y is texture map position (x1,y1), tex2x/tex2y is texture map position (x2,y2)}
  183. var
  184.     tex1xadd,tex1yadd : word;
  185.     xlowadd,xhighadd : word;
  186.     ysize : integer;
  187. asm
  188.     lea    si,cbuffer
  189.     DB LONG; xor cx,cx
  190.     mov    bx,l1                    {get first coords}
  191.     shl    bx,2
  192.     mov    dx,[si+bx]            {get x/y coords}
  193.     mov    cx,[si+bx+2]
  194.  
  195.     mov    ax,l2                    {get second coords}
  196.     shl    ax,2
  197.     add    si,ax
  198.     mov    ax,[si]                {get x/y coords}
  199.     mov    bx,[si+2]
  200.  
  201.     cmp    bx,cx                    {make sure we go downwards...}
  202.     jle    @noswap
  203.     mov    si,[tex1x]            {swap texture x}
  204.     xchg    [tex2x],si
  205.     mov    [tex1x],si
  206.     mov    si,[tex1y]            {swap texture y}
  207.     xchg    [tex2y],si
  208.     mov    [tex1y],si
  209.     xchg    ax,dx                    {swap x}
  210.     xchg    bx,cx                    {sway y}
  211. @noswap:
  212.  
  213.     cmp    bx,[minx]            {record miny and maxy}
  214.     jge    @minx
  215.     mov    [minx],bx
  216. @minx:
  217.     cmp    cx,[maxx]
  218.     jle    @maxx
  219.     mov    [maxx],cx
  220. @maxx:
  221.  
  222.     sub    cx,bx
  223.     and    cx,cx
  224.     jnz    @notzero
  225.     jmp    @zero
  226. @notzero:
  227.     mov    [ysize],cx
  228.     add    bx,bx
  229.     add    bx,bx
  230.     lea    si,slope
  231.     add    si,bx
  232.  
  233.     push    ax
  234.     sub    dx,ax
  235.     inc    dx
  236.  
  237.     mov    ax,dx
  238.     DB LONG; shl    ax,16
  239.     {cdq} DB $66,$99
  240.     DB LONG; idiv    cx
  241.     DB LONG; mov    dx,ax
  242.     DB LONG; shr    dx,16
  243.     mov    [xlowadd],ax
  244.     mov    [xhighadd],dx
  245.  
  246.     mov    ah,BYTE PTR [tex2x]
  247.     sub    ah,BYTE PTR [tex1x]
  248.     xor    al,al
  249.     cwd
  250.     idiv    cx
  251.     mov    [tex1xadd],ax
  252.  
  253.     mov    ah,BYTE PTR [tex2y]
  254.     sub    ah,BYTE PTR [tex1y]
  255.     xor    al,al
  256.     cwd
  257.     idiv    cx
  258.     mov    [tex1yadd],ax
  259. @one:
  260.     pop    cx
  261.  
  262.     xor    bx,bx
  263.     mov    ah,BYTE PTR [tex1x]
  264.     xor    al,al
  265.     mov    dh,BYTE PTR [tex1y]
  266.     xor    dl,dl
  267.     mov    di,$8000
  268. @loop:
  269.     cmp    [si],di
  270.     jne    @other
  271.     mov    [si],cx
  272.     mov    [si+TYPE(SlopeType)],ah
  273.     mov    [si+TYPE(SlopeType)+1],dh
  274.     add    si,4
  275.     add    bx,[xlowadd]
  276.     adc    cx,[xhighadd]
  277.     add    ax,[tex1xadd]
  278.     add    dx,[tex1yadd]
  279.     dec    [ysize]
  280.     jnz    @loop
  281.     jmp    NEAR PTR @zero
  282. @other:
  283.     mov    [si+2],cx
  284.     mov    [si+TYPE(SlopeType)+2],ah
  285.     mov    [si+TYPE(SlopeType)+3],dh
  286.     add    si,4
  287.     add    bx,[xlowadd]
  288.     adc    cx,[xhighadd]
  289.     add    ax,[tex1xadd]
  290.     add    dx,[tex1yadd]
  291.     dec    [ysize]
  292.     jnz    @loop
  293. @zero:
  294. end;
  295.  
  296.  
  297. (*------------------------------------------------*)
  298.  
  299. procedure CalcAngle;
  300. begin
  301.     sin1:=sinustabel[v1]; cos1:=sinustabel[v1+128];
  302.     sin2:=sinustabel[v2]; cos2:=sinustabel[v2+128];
  303.     sin3:=sinustabel[v3]; cos3:=sinustabel[v3+128];
  304.     v1:=(v1+2) AND 511; {change rotation angle}
  305.     v2:=(v2-1) AND 511;
  306.     v3:=(v3-1) AND 511;
  307. end;
  308.  
  309. procedure RotateAllCoords; assembler;
  310. {Rotate all coords in "coords" around all 3 axis and make
  311.  perspective calcualtion. Store x,y,z results in "cbuffer"}
  312. var
  313.     xkoord,ykoord,zkoord, n : integer;
  314. asm
  315.     mov    ax,ds
  316.     mov    es,ax
  317.     lea    si,coords
  318.     lea    di,cbuffer
  319.     mov    [n],NUMBER_COORDS
  320.     cld
  321. @loop:
  322.     lodsw
  323.     mov    [xkoord],ax
  324.     lodsw
  325.     mov    [ykoord],ax
  326.     lodsw
  327.     mov    [zkoord],ax
  328.  
  329.     mov    ax,[xkoord]             {rotate around Z-axis}
  330.     push    ax
  331.     imul    [Cos1]
  332.     add    ax,ax
  333.     adc    dx,dx
  334.     mov    bx,dx
  335.     mov    ax,[ykoord]
  336.     imul    [Sin1]
  337.     add    ax,ax
  338.     adc    dx,dx
  339.     sub    bx,dx
  340.     mov    [xkoord],bx
  341.     pop    ax
  342.     imul    [Sin1]
  343.     add    ax,ax
  344.     adc    dx,dx
  345.     mov    bx,dx
  346.     mov    ax,[ykoord]
  347.     imul    [Cos1]
  348.     add    ax,ax
  349.     adc    dx,dx
  350.     add    bx,dx
  351.     mov    [ykoord],bx
  352.  
  353.     mov    ax,[ykoord]             {rotate around Y-axis}
  354.     push    ax
  355.     imul    [Cos2]
  356.     add    ax,ax
  357.     adc    dx,dx
  358.     mov    bx,dx
  359.     mov    ax,[zkoord]
  360.     imul    [Sin2]
  361.     add    ax,ax
  362.     adc    dx,dx
  363.     sub    bx,dx
  364.     mov    [ykoord],bx
  365.     pop    ax
  366.     imul    [Sin2]
  367.     add    ax,ax
  368.     adc    dx,dx
  369.     mov    bx,dx
  370.     mov    ax,[zkoord]
  371.     imul    [Cos2]
  372.     add    ax,ax
  373.     adc    dx,dx
  374.     add    bx,dx
  375.     mov    [zkoord],bx
  376.  
  377.     mov    ax,[xkoord]             {rotate around X-axis}
  378.     push    ax
  379.     imul    [Cos3]
  380.     add    ax,ax
  381.     adc    dx,dx
  382.     mov    bx,dx
  383.     mov    ax,[zkoord]
  384.     imul    [Sin3]
  385.     add    ax,ax
  386.     adc    dx,dx
  387.     sub   bx,dx
  388.     mov    [xkoord],bx
  389.     pop    ax
  390.     imul    [Sin3]
  391.     add    ax,ax
  392.     adc    dx,dx
  393.     mov    bx,dx
  394.     mov    ax,[zkoord]
  395.     imul    [Cos3]
  396.     add    ax,ax
  397.     adc    dx,dx
  398.     add    bx,dx
  399.     mov    [zkoord],bx
  400.  
  401.     add    bx,800
  402.     and    bx,bx
  403.     jnz    @zero
  404.     mov    bl,1
  405. @zero:
  406.  
  407.     mov    ax,[xkoord]
  408.     cwd
  409.     mov    dl,ah
  410.     mov    ah,al
  411.     xor    al,al
  412.     idiv    bx
  413.     add    ax,100
  414.     stosw
  415.  
  416.     mov    ax,[ykoord]
  417.     cwd
  418.     mov    dl,ah
  419.     mov    ah,al
  420.     xor    al,al
  421.     idiv    bx
  422.     add    ax,160
  423.     stosw
  424.  
  425.     dec    [n]
  426.     jnz    @loop
  427. end;
  428.  
  429.  
  430.  
  431. function FaceShown(i : integer; l1,l2,l3 : word) : boolean;
  432. var
  433.     a,b : longint;
  434. begin
  435.     a := LongMul(cbuffer[l1]-cbuffer[l2],cbuffer[l3+1]-cbuffer[l2+1]);
  436.     b := LongMul(cbuffer[l1+1]-cbuffer[l2+1],cbuffer[l3]-cbuffer[l2]);
  437.     FaceShown := (a-b) > 0;
  438.     light[i]:=15-LongDiv(a-b,490);
  439. end;
  440.  
  441.  
  442. procedure FillShape(x,xsize : integer; light : word); assembler;
  443. {Fill textured polygon by texturing vertical lines.
  444.  Slow because of byte writes to VGA memory!}
  445. var
  446.     tex1,tex2 : word;
  447.     xlowadd,xhighadd,ylowadd,yhighadd : word;
  448.     loops : word;
  449.     bitxpos : byte;
  450. asm
  451.     cmp    [xsize],320
  452.     jb        @drawit
  453.     jmp    @done
  454. @drawit:
  455.     mov    di,[display1]
  456.     mov    ax,[x]
  457.     shr    ax,2
  458.     add    di,ax
  459.  
  460.     lea    si,slope
  461.     mov    ax,[x]
  462.     mov    cx,ax
  463.     shl    ax,2
  464.     add    si,ax
  465.  
  466.     and    cl,3
  467.     mov    al,$11
  468.     shl    al,cl
  469.     mov    [bitxpos],al
  470.  
  471.     mov    es,[SEGA000]
  472.     cld
  473. @xloop:
  474.     mov    dx,$3C4
  475.     mov    ah,[bitxpos]
  476.     mov    al,$02
  477.     out    dx,ax
  478.  
  479.     mov    cx,[si+TYPE(slopetype)] {fetch texture x,y values}
  480.     lodsw                                    {fetch first ypos}
  481.     mov    dx,ax
  482.     mov    bx,[si+TYPE(slopetype)] {fetch second texture x,y values}
  483.     lodsw                                    {fetch second ypos}
  484.     cmp    ax,dx                            {need to go downwards..}
  485.     jle    @exchange
  486.     xchg    ax,dx
  487.     xchg    cx,bx
  488. @exchange:
  489.     mov    [tex1],cx
  490.     mov    [tex2],bx
  491.  
  492.     push    si
  493.     push    di
  494.  
  495.     DB LONG; xor cx,cx
  496.     mov    cx,dx
  497.     sub    cx,ax
  498.     or        cx,cx
  499.     jnz    @y_is_great
  500.     jmp    @filledout
  501. @y_is_great:
  502.     add    ax,ax
  503.     mov    bx,ax
  504.     add    di,[OFFSET ytabel+bx]
  505.     mov    [loops],cx
  506.  
  507.     push    ds
  508.     push    bp
  509.  
  510.     mov    al,BYTE PTR [tex1]
  511.     sub    al,BYTE PTR [tex2]
  512.     cbw
  513.     DB LONG; shl    ax,16
  514.     {cdq} DB $66,$99
  515.     DB LONG; idiv    cx
  516.     DB LONG; mov    dx,ax
  517.     DB LONG; shr    dx,16
  518.     mov    [xlowadd],ax
  519.     mov    [xhighadd],dx
  520.  
  521.     mov    al,BYTE PTR [tex1+1]
  522.     sub    al,BYTE PTR [tex2+1]
  523.     cbw
  524.     DB LONG; shl    ax,16
  525.     {cdq} DB $66,$99
  526.     DB LONG; idiv    cx
  527.     DB LONG; mov    dx,ax
  528.     DB LONG; shr    dx,16
  529.     mov    [ylowadd],ax
  530.     mov    [yhighadd],dx
  531.  
  532.     DB LONG; xor dx,dx
  533.     mov    dx,[yhighadd]
  534.  
  535.     mov    ax,[xlowadd]
  536.     DB LONG; shl ax,16
  537.  
  538.     mov    bx,[ylowadd]
  539.     DB LONG; shl bx,16
  540.     mov    bx,[xhighadd]
  541.     DB LONG; mov si,bx
  542.  
  543.     DB LONG; xor bx,bx
  544.     mov    bl,BYTE PTR [tex2]
  545.     mov    bh,BYTE PTR [tex2+1]
  546.     DB LONG; xor cx,cx
  547.     mov    cx,[loops]
  548.     mov    ds,WORD PTR [texture+2]
  549.     mov    bp,[light]
  550. @loop:
  551.     DB LONG; add cx,ax
  552.     DB LONG; adc bx,si
  553.     adc    bh,dl
  554.     mov    dh,[bx]
  555.     add    dx,bp                {add light factor}
  556.     mov    [es:di],dh
  557.     add    di,80
  558.     dec    cx
  559.     jnz    @loop
  560.  
  561.     pop    bp
  562.     pop    ds
  563.  
  564. @filledout:
  565.     pop    di
  566.     pop    si
  567. @filledout_fast:
  568.     rol    [bitxpos],1
  569.     adc    di,0
  570.     dec    [xsize]
  571.     jnz    @xloop
  572. @done:
  573. end;
  574.  
  575.  
  576. procedure RunOnce;
  577. var
  578.     i : integer;
  579. begin
  580.     SwapDisplay;
  581.     VBLANK;
  582. {$IFDEF DEBUG}
  583.     SetRGB(0,16,0,0);
  584. {$ENDIF}
  585.  
  586.     ClearScreen;
  587.  
  588.     CalcAngle;
  589.     RotateAllCoords;
  590.  
  591.     for i:=1 to NUMBER_FACES do begin
  592.         with face[i] do if FaceShown(i, l1 SHL 1,l2 SHL 1,l3 SHL 1) then begin
  593.             ClearSlope;
  594.             minx := 320; maxx := 0;
  595.             CalcSlope(l1,l2, 0,0,127,0);
  596.             CalcSlope(l2,l3, 127,0,127,127);
  597.             CalcSlope(l3,l4, 127,127,0,127);
  598.             CalcSlope(l4,l1, 0,127,0,0);
  599.             FillShape(minx, maxx-minx, light[i] SHL 12);
  600.         end;
  601.     end;
  602.  
  603. {$IFDEF DEBUG}
  604.     SetRGB(0,0,0,0);
  605.     while KeyHit[26] do ; {Hit 'P' to pause}
  606. {$ENDIF}
  607. end;
  608.  
  609.  
  610. begin
  611.     OpenScreen;
  612.     InitDemo;
  613.     SetAllInterrupts;
  614.     repeat RunOnce until Key='e';
  615.     RestoreAllInterrupts;
  616.     UninitDemo;
  617.     CloseScreen;
  618. end.
  619.